﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Communication.Common;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Utilities;

namespace Communication.Udp
{
    public class UdpServer : IServer
    {
        private int port = 0;
        UdpClient udpclient = null;
        Thread receiveThread = null;
        Thread sendThread = null;


        public int Port
        {
            get
            {
                return port;
            }

            set
            {

                port = value;
            }
        }

        public void StartReceive()
        {
            if (udpclient == null)
            {
                if (Port != 0)
                    udpclient = new UdpClient(Port);
                else
                    udpclient = new UdpClient();
            }
            receiveThread = new Thread(Receive);
            receiveThread.IsBackground = true;
            receiveThread.Start();
        }

        public void StopReceive()
        {
            if (sendThread == null || !sendThread.IsAlive)
            {
                udpclient.Close();
                udpclient = null;
            }
            receiveThread.Abort();
            receiveThread = null;
        }

        public void StartSend()
        {
            if (udpclient == null)
                udpclient = new UdpClient(Port);
            sendThread = new Thread(Send);
            sendThread.IsBackground = true;
            sendThread.Start();
        }

        public void StopSend()
        {
            if (receiveThread == null || !receiveThread.IsAlive)
            {
                udpclient.Close();
                udpclient = null;
            }
            sendThread.Abort();
            sendThread = null;
        }

        private void Receive()
        {
            IPEndPoint ipendpoint = new IPEndPoint (IPAddress.Any,0);
            byte[] bytes;
            while (true)
            {
                bytes = udpclient.Receive(ref ipendpoint);
                Message msg = SerializationHelper.FromBytes<Message>(bytes);
                EventMessage em = new EventMessage() { Message = msg, IPEndPoints = new IPEndPoint[]{ipendpoint} };
                EventMessageManager.CurrentEventMessageManager.AddReceivedEventMessage(em);
            }
        }

        private void Send()
        {
            EventMessage em;
            while (true)
            { 
                 em = EventMessageManager.CurrentEventMessageManager.GetSentEventMessage();
                byte[] bytes;
                 if (em != null)
                 {
                     //
                     bytes = SerializationHelper.ToBytes<Message>(em.Message);
                     foreach (var ip in em.IPEndPoints)
                     {
                         udpclient.Send(bytes, bytes.Length, ip);
                     }
                 }
                 else
                 {
                     Thread.Sleep(1000);
                 }
            }
        }
    }
}
